﻿using System.Linq;
using Roslyn.Compilers.CSharp;

namespace InterfaceWeaver.CustomTool
{
    public static class PropertyDeclarationSyntaxExtensions
    {
        public static bool IsOfType<T>(this PropertyDeclarationSyntax property)
        {
            if (property != null)
            {
                var typeIdentifier = property.Type as IdentifierNameSyntax;
                if (typeIdentifier != null)
                {
                    var typeText = typeIdentifier.Identifier.ValueText;
                    var longTypeSplitted = typeText.Split('.');

                    // TODO: extend the test to more possibilities
                    return longTypeSplitted.Last() == typeof (T).Name || typeText == typeof (T).FullName;
                }
            }

            return false;
        }

        /// <summary>
        /// Determines whether the specified property has accessor.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <param name="accessorName">Name of the accessor.</param>
        /// <returns>
        ///   <c>true</c> if the specified property has accessor; otherwise, <c>false</c>.
        /// </returns>
        public static bool HasAccessor(this PropertyDeclarationSyntax property, string accessorName)
        {
            return property.AccessorList.Accessors.Any(acc => acc.Keyword.Value.ToString() == accessorName);
        }

        /// <summary>
        /// Determines whether the specified property has getter.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <returns>
        ///   <c>true</c> if the specified property has getter; otherwise, <c>false</c>.
        /// </returns>
        public static bool HasGetter(this PropertyDeclarationSyntax property)
        {
            return property.HasAccessor("get");
        }

        /// <summary>
        /// Determines whether the specified property has setter.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <returns>
        ///   <c>true</c> if the specified property has setter; otherwise, <c>false</c>.
        /// </returns>
        public static bool HasSetter(this PropertyDeclarationSyntax property)
        {
            return property.HasAccessor("set");
        }

        /// <summary>
        /// Finds the accessor.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <param name="accessorName">Name of the accessor.</param>
        /// <returns></returns>
        public static AccessorDeclarationSyntax FindAccessor(this PropertyDeclarationSyntax property, string accessorName)
        {
            return property.AccessorList.Accessors.FirstOrDefault(acc => acc.Keyword.Value.ToString() == accessorName);
        }

        /// <summary>
        /// Finds the getter.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <returns></returns>
        public static AccessorDeclarationSyntax FindGetter(this PropertyDeclarationSyntax property)
        {
            return property.FindAccessor("get");
        }

        /// <summary>
        /// Finds the setter.
        /// </summary>
        /// <param name="property">The property.</param>
        /// <returns></returns>
        public static AccessorDeclarationSyntax FindSetter(this PropertyDeclarationSyntax property)
        {
            return property.FindAccessor("set");
        }
    }
}
